#ifndef BACKPACK_HOTSPOT_VARIANT_H_
#define BACKPACK_HOTSPOT_VARIANT_H_

#include <boost/variant.hpp>
#include <functional>

namespace backpack {

class TouchPoint;
class UnlockPoint;
class WayPoint;


// all usable hotspot types must be added to HotSpotVariant type
typedef boost::variant<
	std::reference_wrapper<TouchPoint>,
  std::reference_wrapper<UnlockPoint>,
  std::reference_wrapper<WayPoint>
> HotSpotVariant;



extern const HotSpotVariant g_hotSpotNull;



inline bool operator!=(HotSpotVariant const& lhs, HotSpotVariant const& rhs) {
  return !(lhs == rhs);
}



template <class Visitor, class ReturnType = void>
class HotSpotVisitor : public boost::static_visitor<ReturnType> {
public:
  HotSpotVisitor(Visitor &&v)
    : m_visitor(std::forward<Visitor>(v)) {
  }
  template <class HotSpot>
  ReturnType operator() (
      std::reference_wrapper<HotSpot> const& wrapper) const {
    return m_visitor(wrapper.get());
  }
  template <class HotSpot>
  ReturnType operator() (
      std::reference_wrapper<HotSpot> const& wrapper) {
    return m_visitor(wrapper.get());
  }
private:
  Visitor m_visitor;
}; // class HotSpotVisitor



template <class ReturnType = void, class Visitor>
HotSpotVisitor<Visitor, ReturnType> makeHotSpotVisitor(Visitor &&v) {
  return HotSpotVisitor<Visitor, ReturnType>(std::forward<Visitor>(v));
}




} // namespace backpack

#endif // BACKPACK_HOTSPOT_VARIANT_H_

